/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package DTD.Validador;

import DTD.DTDValidadorSintaxis;
import Excepciones.DTDException;

/**
 *
 * @author Administrador
 */
public class ValidadorItem {

    private String nombre;
    private String elementInterno;
    private String elementExterno;
    private String attlistInterno;
    private String attlistExterno;
    //banderas correspondientes a identificar si las reglas fueron utilizadas
    private boolean elementInternoUsado;
    private boolean elementExternoUsado;
    //banderas correspondientes a identificar si las reglas deben usarse
    private boolean debeUsarReglaInterna;
    private boolean debeUsarReglaExterna;
    private boolean reglaInternaVacia;
    private boolean reglaExternaVacia;
    private boolean aux;

    public ValidadorItem(String nombre) {
        this.nombre = nombre;
    }

    public String getNombre() {
        return nombre;
    }

    public boolean validar(String aValidar) {
        return true;
    }

    public String getReglaAttList(boolean esInterna) {
        String resultado = this.attlistExterno;

        if (esInterna) {
            resultado = this.attlistInterno;
        }
        return resultado;
    }

    public String getReglaElement(boolean esInterna) {
        String resultado = null;

        if (esInterna) {
            resultado = this.elementInterno;
            this.elementInternoUsado = (resultado != null);
        }
        else {
            resultado = this.elementExterno;
            this.elementExternoUsado = (resultado != null);
        }
        return resultado;
    }

    public void addRegla(String regla, boolean esInterna, int tipo) throws DTDException {

        switch (tipo) {
            case DTDValidadorSintaxis.ATTLIST:
                this.setAttlist(regla, esInterna);
                break;
            case DTDValidadorSintaxis.ELEMENT:
                this.setElement(regla, esInterna);
                break;
            default:
                break;
        }
        showMsg(regla, esInterna, tipo);
    }

    private boolean getDebeUsarRegla(String regla) {
        boolean resultado = false;

        try {
            char c = ' ';

            for (int i = regla.length() - 2; i >= 0 && c == ' '; i--) {
                c = regla.charAt(i);
            }

            switch (c) {
                case '+':
                    resultado = true;
                    break;
                case ')':
                    resultado = true;
                    break;
                case '*':
                    this.aux = true;
                    break;
                default:
                    resultado = false;
                    break;
            }

        } catch (IndexOutOfBoundsException e) {
            resultado = false;
        }
        return resultado;
    }

    private boolean getReglaVacia(String regla) {
        return (regla.indexOf("EMPTY") != -1);
    }

    private void setElement(String regla, boolean esInterna) throws DTDException {
        if (esInterna) {
            if (this.elementInterno != null) {
                throw new DTDException("El element existe");
            }
            else {
                this.elementInterno = regla;
                this.debeUsarReglaInterna = getDebeUsarRegla(regla);
                this.reglaInternaVacia = getReglaVacia(regla);
            }
        }
        else {
            if (this.elementExterno != null) {
                throw new DTDException("El element existe");
            }
            else {
                this.elementExterno = regla;
                this.debeUsarReglaExterna = getDebeUsarRegla(regla);
                this.reglaExternaVacia = getReglaVacia(regla);
            }
        }
    }

    private void setAttlist(String regla, boolean esInterna) throws DTDException {
        if (esInterna) {
            if (this.attlistInterno != null) {
                throw new DTDException("El attList existe");
            }
            else {
                this.attlistInterno = regla;
            }
        }
        else {
            if (this.attlistExterno != null) {
                throw new DTDException("El attList existe");
            }
            else {
                this.attlistExterno = regla;
            }
        }
    }

    private void showMsg(String regla, boolean esInterna, int tipo) {
        String tn = ">>>>>>>>>>>>> " + this.nombre;

        if (esInterna) {
            tn += " (INTERNA ";
        }
        else {
            tn += "(EXTERNA ";
        }

        switch (tipo) {
            case DTDValidadorSintaxis.ATTLIST:
                tn += "ATTLIST REGLA) ";
                break;
            case DTDValidadorSintaxis.ELEMENT:
                tn += "ELEMENT REGLA) ";
                break;
            default:
                break;
        }

        tn += regla;
        System.out.println(tn);
    }

    public boolean usoCorrectoDeReglas() {
        boolean resultado = true;

        if (!this.reglaInternaVacia && !this.reglaExternaVacia) {
            resultado = ((this.debeUsarReglaInterna == this.elementInternoUsado) &&
                         (this.debeUsarReglaExterna == this.elementExternoUsado))||(this.aux);
        }
        else {
            resultado = true;
        }
        return resultado;
    }
}
